/** @file 
 *	@class StateManager
 *  @brief The StateManager class that makes sure all controllers are updated
 *
 *  The StateManager starts and switches between states. It inherits from the Ogre Framelistener, and uses the
 *	frameRenderingQueued method to run the update method of the currently active state
 */

#include "stdafx.h"
#include "Controller.h"
#include "GameState.h"
#include "MainMenuState.h"
#include <string>
#include <list>

#ifndef __StateManager_h_
#define __StateManager_h_

class MainMenuState;
class StateManager : public Ogre::FrameListener
{
public:

	/**
	* @Brief Handles pressing the quit button event by passing false to FrameRenderingQueued in StateManager
	*
	* This method handles shutting off the game after the quit button is clickedby by setting m_shutdown=true. 
	* It is called from a similarly named function, dependent on CEGUI, in MainMenuGUIController
	*/
	void quitGame();
	bool m_shutdown;

	/**
	* @Brief Moves to the GameState when the Start Game button event is triggered
	* 
	* This method initializes the new GameState
	*/
	void startGame();

	/**
	* @brief Returns a pointer to the StateManager singleton
	*/
	static StateManager* getInstance();
	/**
	* @brief The destructor
	*/
	~StateManager();

	/**
	* @brief Set the state and delete the old state if it exists
	*/
	void setState(State* state);
	/**
	* @brief Points m_root to the ogre root
	*
	* Points m_root to the ogre root, and registers the StateManager as a framelistener
	* so frameRenderingQueued is called
	*/
	void setRoot(Ogre::Root* root);
	/**
	* @brief Returns the ogre root node
	*/
	Ogre::Root* getRoot();
	/**
	* @brief Sets m_window to the renderwindow
	*/
	void setWindow(Ogre::RenderWindow* window);
	/**
	* @brief Returns the renderwindow
	*/
	Ogre::RenderWindow* getWindow();

	/**
	* @brief A method for starting the main menu state
	*/
	void startMenuState();
	/**
	* @brief Sets the game state flag and passes on the IP from the main menu
	*/
	void startGameStateFlagged(string ip);
	/**
	* @brief Sets the replay flag and passes on the default (local session) IP 
	*/
	void startReplayState();

private:
	/**
	* @brief Handles shutdown, updates input manager,  updates all controllers updates
	*
	* Returns false if the m_shutdown is true, which makes the application shuts down. Updates the input manager and calls the
	* update method for the current state and passes deltatime to it. 
	*/
	virtual bool frameRenderingQueued(const Ogre::FrameEvent &evt);
	/**
	* @brief Switches state once the current frame is done, if the game state flag is true.
	*/
	virtual bool frameEnded(const Ogre::FrameEvent &evt);

	static bool instanceFlag;
	/**
	* @brief Pointer to the statemanager instance which the getInstance method returns
	*/
	static StateManager* stateManager;
	/**
	* @brief A private constructor to keep with good singleton-design
	*/
	StateManager();

	/**
	* @brief A method for starting the game state
	*/
	void startGameState();

	/**
	* @brief Member variable holding the current state, typically either MainMenuState or GameState
	*/ 
	State* m_currentState;

	Ogre::Root* m_root;
	Ogre::RenderWindow* m_window;
	

	GameState* gameState;
	MainMenuState* mainMenuState;

	/**
	* @brief A bool checked by frameEnded so state transitions are done once frame rendering is done
	*/ 
	bool startGameStateFlag;

	/**
	* @brief A bool set when the user clicks the replay button in the main menu
	*/ 
	bool replayMode;

	std::string ip;
	std::string defaultIP;

	static const float update_time;
	static float execution_time;
};


#endif //#ifndef __StateManager_h_